// Commands.h : Declaration of the CCommands

#ifndef __COMMANDS_H_
#define __COMMANDS_H_

#include "resource.h"       // main symbols
#include "guids.h"
#include "../vmlib/MindBaseCtl.h"

/////////////////////////////////////////////////////////////////////////////
// CCommands

class Cvmbase;

class ATL_NO_VTABLE CCommands : 
	public CComObjectRootEx<CComMultiThreadModel>,
	public CComCoClass<CCommands, &CLSID_Commands>,
	public IDispatchImpl<ICommands, &IID_ICommands, &LIBID_VMBASELib>,
	public I_MindBaseCtlCallback
{
public:

DECLARE_NOT_AGGREGATABLE(CCommands)

BEGIN_COM_MAP(CCommands)
	COM_INTERFACE_ENTRY(ICommands)
	COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

friend class Cvmbase;

	void SetApplicationObject(IApplication* m_pApplication);
	IApplication* GetApplicationObject() { return m_pApplication; }
	void UnadviseFromEvents();

protected:
	// This class template is used as the base class for the Application
	//  event handler object and the Debugger event handler object,
	//  which are declared below.
	template <class IEvents, const IID* piidEvents, const GUID* plibid,
		class XEvents, const CLSID* pClsidEvents>
	class XEventHandler :
		public CComDualImpl<IEvents, piidEvents, plibid>,
		public CComObjectRoot,
		public CComCoClass<XEvents, pClsidEvents>
	{
	public:
		BEGIN_COM_MAP(XEvents)
			COM_INTERFACE_ENTRY(IDispatch)
			COM_INTERFACE_ENTRY_IID(*piidEvents, IEvents)
		END_COM_MAP()
		DECLARE_NOT_AGGREGATABLE(XEvents)
		void Connect(IUnknown* pUnk)
		{ VERIFY(SUCCEEDED(AtlAdvise(pUnk, this, *piidEvents, &m_dwAdvise))); }
		void Disconnect(IUnknown* pUnk)
		{ AtlUnadvise(pUnk, *piidEvents, m_dwAdvise); }

		CCommands* m_pCommands;

	protected:
		DWORD m_dwAdvise;
	};

	// This object handles events fired by the Application object
	class XApplicationEvents : public XEventHandler<IApplicationEvents, 
		&IID_IApplicationEvents, &LIBID_VMBASELib, 
		XApplicationEvents, &CLSID_ApplicationEvents>
	{
	public:
		// IApplicationEvents methods
		STDMETHOD(BeforeBuildStart)(THIS);
		STDMETHOD(BuildFinish)(THIS_ long nNumErrors, long nNumWarnings);
		STDMETHOD(BeforeApplicationShutDown)(THIS);
		STDMETHOD(DocumentOpen)(THIS_ IDispatch * theDocument);
		STDMETHOD(BeforeDocumentClose)(THIS_ IDispatch * theDocument);
		STDMETHOD(DocumentSave)(THIS_ IDispatch * theDocument);
		STDMETHOD(NewDocument)(THIS_ IDispatch * theDocument);
		STDMETHOD(WindowActivate)(THIS_ IDispatch * theWindow);
		STDMETHOD(WindowDeactivate)(THIS_ IDispatch * theWindow);
		STDMETHOD(WorkspaceOpen)(THIS);
		STDMETHOD(WorkspaceClose)(THIS);
		STDMETHOD(NewWorkspace)(THIS);
	};
	typedef CComObject<XApplicationEvents> XApplicationEventsObj;
	XApplicationEventsObj* m_pApplicationEventsObj;

private:

	CComPtr<IApplication>	m_pApplication;

public:
	bool DoFindNearestMcmt(ITextSelection *pSelection);
	bool DoFindMcmt(ITextSelection *pSelection, LPCTSTR sMcmt);
	void DoAddMcmt(ITextSelection *pSelection, LPCTSTR sPath);
	void DoCloseBase();
	void DoOpenBase();
	void DoOpenDocument(LPCTSTR sDocPath, LPCTSTR sMetaCmt);

	void mbc_OpenDoc(LPCTSTR szDoc, LPCTSTR szMcmt);
	
	CCommands();

// ICommands
public:
	CString GetWorkspacePath();
	STDMETHOD(Mindbase_AddMcmt)(THIS);
	STDMETHOD(Mindbase_DelMcmt)(THIS);
	STDMETHOD(Mindbase_EditMdata)(THIS);
	STDMETHOD(Mindbase_GetInfo)(THIS);
	STDMETHOD(Mindbase_ShowTree)(THIS);
	STDMETHOD(Mindbase_Query)(THIS);
	STDMETHOD(Mindbase_Report)(THIS);
	STDMETHOD(Mindbase_Options)(THIS);
};

typedef CComObject<CCommands> CCommandsObj;

#endif //__COMMANDS_H_
